CocoaPodsによる、外部ライブラリの利用と作成
CocoaPodsとは
CocoaPodsとは、定番のCocoaの依存管理マネージャーです。アプリ開発で煩雑となりがちな外部ライブラリの管理を、簡単な記述とコマンドだけ支援するものです。
ざっくりと外観してしまうと・・・CocoaPodsは、Podfileに記述されたライブラリを、メタ情報をもとにダウンロードし、それらをまとめたPodsプロジェクトを生成します。 そして、ワークスペースの仕組みを利用して、既存のプロジェクトから、これを参照できるようにしています。
以下、動作について詳しく見ていきます。
2 インストール及び管理情報
(1) インストール
Macには、あらかじめRubyがインストールされているため、下記のコマンドでインストールできます。
$sudo gem update --system <=ruby gemを最新にする $sudo gem install cocoapods
(2) setupコマンド
setupコマンドで、github上のメタデータ(管理情報)「https://github.com/CocoaPods/Specs」が、ローカルの「~/.cocoapods」に展開されます。
$ pod setup
次の図は、setup実行後に「https://github.com/CocoaPods/Specs/tree/master/Specs」をブラウザで表示したものと、ローカルのディスクを一覧したものの比較です。
$ pwd /Users/SIN/.cocoapods/repos/master/Specs $ ls -la | head -n 15 total 0 drwxr-xr-x 14245 SIN staff 484330 12 17 00:46 . drwxr-xr-x 7 SIN staff 238 11 5 11:05 .. drwxr-xr-x 10 SIN staff 340 12 16 02:54 120301 drwxr-xr-x 3 SIN staff 102 12 16 02:54 1210 drwxr-xr-x 6 SIN staff 204 12 16 02:54 12306DeveCocoa drwxr-xr-x 22 SIN staff 748 12 16 02:54 1PasswordExtension drwxr-xr-x 4 SIN staff 136 10 5 17:26 1PasswordExtensionHaha drwxr-xr-x 14 SIN staff 476 10 5 17:26 25519 drwxr-xr-x 4 SIN staff 136 10 5 17:26 320Categories drwxr-xr-x 3 SIN staff 102 11 5 11:05 3DTouchHelper drwxr-xr-x 6 SIN staff 204 10 5 17:26 500px-iOS-api drwxr-xr-x 3 SIN staff 102 10 5 17:26 7blur drwxr-xr-x 3 SIN staff 102 10 5 17:26 A drwxr-xr-x 14 SIN staff 476 10 5 17:26 A2DynamicDelegate
それぞれのライブラリ名の中には、バージョン(実際にはgitのtag)名のフォルダとなっており、その中、下記のようなJSONファイル(ライブラリ名.podspec.json)が置かれいます。
次の図は、「Alamofire/3.1.3」の中の「Alamofire.podspec.json」を表示したものです。
podspec.json というファイルには、ライブラリの入手先(github)や、ビルド方法の定義が入ったメタデータとなっていることが確認できます。 CocoaPodsは、このファイルをもとに、ライブラリの管理を行っています。
なお、後述するinstallコマンドの実行時に、毎回ローカルの管理情報は更新されるため、setupコマンドをあまり意識する必要はないようです。
$ rm ーrf /Users/SIN/.cocoapods/repos/master <= 管理情報(masterフォルダ)の削除 $ pod install Creating shallow clone of spec repo `master` from `https://github.com/CocoaPods/Specs.git` <= masterフォルダの再構築 Updating local specs repositories ・・・省略・・・
(3) listコマンド
この管理情報の内容は、listコマンドで一覧することができます。 次の例は、Alamofireの情報を確認している様子ですが、「Alamofire」が利用可能なことと、最新バージョンが「3.1.3」であることが分かります。
※listコマンドは大量の出力があるためgrep等の併用をお勧めします。
$ pod list | grep Alamofire Alamofire 3.1.3 Alamofire+Result 3.0.0-karumi Alamofire-Prephirences 1.0.1 ・・・省略・・・
念のため、ファイルを確認してみると次のようになっています。
$ pwd /Users/SIN/.cocoapods/repos/master/Specs/Alamofire $ ls -al ・・・省略・・・ drwxr-xr-x 3 SIN staff 102 12 17 02:18 3.1.1 drwxr-xr-x 3 SIN staff 102 12 17 02:18 3.1.2 drwxr-xr-x 3 SIN staff 102 12 17 02:18 3.1.3
listコマンドは、あくまでもローカルの情報を確認するコマンドであり、github上の最新情報を見るためのものではありません。
3 外部ライブラリの使用方法
最初に、既存のプロジェクトに外部のライブラリを組み込む要領について見ていきます。
(1) initコマンド
Xcodeプロジェクトのフォルダの中で、initコマンドを打つと、Podfileの雛形が生成されます。
$ pod init $ cat Podfile # Uncomment this line to define a global platform for your project # platform :ios, '8.0' # Uncomment this line if you're using Swift # use_frameworks! target 'Sample001' do end
(2) ライブラリ指定
この中に、取り込みたい外部ライブラリの情報を記載します。
次の例では、「Alamofire」を追加するように指定しています。
$ cat Podfile # Uncomment this line to define a global platform for your project # platform :ios, '8.0' # Uncomment this line if you're using Swift use_frameworks! target 'Sample001' do pod 'Alamofire', '~> 3.0' end
なお、ライブラリの指定方法ですが、単純に最新のバージョンを取得したい場合は、ライブラリ名だけを指定します。
pod 'Alamofire'
そして、バージョンを指定したい場合は、その後ろにそれを記述します。
pod 'Alamofire', '~> 3.0'
[バージョンの指定方法]
記述 | 意味 |
’1.0’ | バージョン1.0を使用 |
’> 1.0’ | 1.0 より上のバージョンを使用 |
’>= 1.0’ | 1.0 以上のバージョンを使用 |
’< 1.0’ | 1.0 未満のバージョンを使用 |
’<= 1.0’ | 1.0 以下のバージョンを使用 |
’~> 0.1.2’ | マイナーバージョン内での使用 0.1.2以降、0.2未満(すなわち0.1.2以降の0.1.x) |
’~> 0.1'’ | マイナーバージョン内での使用 0.1以降、1.0未満 |
ライブラリの取得先は、管理情報(メタデータ)に従わずに直接指定することも可能です。
ローカルのフォルダを指定する場合
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
git上のmasterブランチを使用する場合
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
git上の特定のブランチを使用する場合
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'
tagを指定する場合
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'
特定のコミットを使用する場合
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
(3) installコマンド
Podfileの設定完了後、installコマンドでライブラリの取り込みが始まります。 (この時、xcodeでプロジェクトファイルを開いているとエラーが発生するという情報を見かけますが、現在は、特に問題ないようです。)
$pod install
installコマンドが実行されると、プロジェクトのフォルダ内に、Podfile.lock、ワークスペースファイル(.xcworkspace)、そしてPodsフォルダが作成されます。
$ ls -la total 16 drwxr-xr-x 8 SIN staff 272 12 17 03:11 . drwxr-xr-x 28 SIN staff 952 12 17 00:56 .. -rw-r--r-- 1 SIN staff 208 12 17 01:59 Podfile -rw-r--r-- 1 SIN staff 156 12 17 02:53 Podfile.lock <= lockファイル drwxr-xr-x 8 SIN staff 272 12 17 02:55 Pods <= 外部ライブラリがダウンロードされたフォルダ drwxr-xr-x 8 SIN staff 272 12 17 02:51 Sample001 drwxr-xr-x@ 5 SIN staff 170 12 17 01:59 Sample001.xcodeproj drwxr-xr-x 4 SIN staff 136 12 17 02:55 Sample001.xcworkspace <= ワークスペースファイル
Podfile.lockには、実際に取り込んだバージョンの情報が記載されています。
$ cat Podfile.lock PODS: - Alamofire (3.1.3) DEPENDENCIES: - Alamofire (~> 3.0) SPEC CHECKSUMS: Alamofire: 9f93b56389e48def9220dd57d1f44b1927229a5a COCOAPODS: 0.39.0
Podsフォルダの中には、Podsというプロジェクトがあり、このプロジェクトが取り込んだライブラリと取りまとめ、ワークスペースの機能を利用して既存のプロジェクトから参照される仕組みになっています。
$ ls -la Pods total 8 drwxr-xr-x 8 SIN staff 272 12 17 02:55 . drwxr-xr-x 8 SIN staff 272 12 17 03:11 .. drwxr-xr-x 5 SIN staff 170 12 17 01:59 Alamofire drwxr-xr-x 2 SIN staff 68 12 17 02:55 Headers drwxr-xr-x 2 SIN staff 68 12 17 01:57 Local Podspecs -rw-r--r-- 1 SIN staff 156 12 17 02:55 Manifest.lock drwxr-xr-x 4 SIN staff 136 12 17 02:55 Pods.xcodeproj drwxr-xr-x 4 SIN staff 136 12 17 02:55 Target Support Files
(4) updateコマンド
ライブラリの更新や、Podfileを編集した場合は、updateコマンドを使用します。
$ pod update
updateにより、Podfileから削除されたライブラリの削除も行われます。
(5) ワークスペースファイル
後は、installコマンドで生成されたワークスペースファイル(.xcworkspace)をXcodeから開いて作業を進めます。
$open Sample001.xcworkspace
Pods/Productsの中のフレームワーク名をimportすることで使用が可能になります。
(6)ワークスペース名の指定
installlコマンドでワークスペースが作成されますが、その名前は、既存のプロジェクト名と同じになります。しかし、既存のワークスペースに統合したい場合や、任意のワークスペース名を指定したい場合は、Podfileに「workspace 」の設定を追加します。
$ ls -la total 0 drwxr-xr-x 5 SIN staff 170 12 17 10:05 . drwxr-xr-x 30 SIN staff 1020 12 17 09:59 .. drwxr-xr-x 4 SIN staff 136 12 17 09:59 Origin.xcworkspace <= OriginワークスペースにSample001プロジェクトが含まれている drwxr-xr-x 7 SIN staff 238 12 17 09:59 Sample001 drwxr-xr-x@ 5 SIN staff 170 12 17 10:01 Sample001.xcodeproj
上記のようなOriginワークスペースに統合したい場合は、下記のように記述します。
$ cat Podfile use_frameworks! workspace 'Origin' target 'Sample001' do pod 'Alamofire', '~> 3.0' end
(7)use_frameworks!
Swift で書かれた Pods(ライブラリ)は、frameworks としてのみ統合できるとの事で、use_frameworks! の行のコメント(#)を外すことを忘れないでください。
(8) .gitignore
プロジェクトをgitで管理する場合、Podfileがあれば、Podsフォルダは、「pod install」で復活できるため、「Pods」を.gitignoreに記載して、Podsフォルダを管理外にすることができます。
しかし、この方法は、復活のためにCocoaPodsのインストールが必須となるなど、一概にメリットだけとは言えないので、それぞれの状況で検討が必要です。
なお、Podfile.lockも「pod install」で生成されますが、こちらは、実際に使用されているバージョンを管理しているものですので、管理外とすることはできません。
4 自作ライブラリの使用方法
次に、自ら作成したフレームワークをCocoaPodsで管理する要領について見ていきます。
手順として、「(1)ライブラリの作成」ー「(2)Demoプロジェクトの作成」という順になっている理由は、最終的に公開するトップのフォルダに、ライブラリのプロジェクトファイルが配置されるようにするためです。
(1) ライブラリの作成
Xcodeで「File」-「New」-「Project」とたどり「iOS」-「Framework & Library」 から「Cocoa Touch Framework」を選択し新しいプロジェクトを作成します。(ここでは、名前を「MyLib」としました)
続いて、「MyLib」の中にSwift Fileを追加します。(名前は、「MyLib.swift」としました)
MyLib.swiftには、ライブラリの機能として、次のような簡単なメソッドを1つだけ定義しました。
import Foundation public class MyLib:NSObject{ public class func start(){ print("MyLib start..") } }
(2) Demoプロジェクトの作成
続いて、動作を確認できるように、ライブラリを使用する側のプロジェクトとして「Demo」という名前のプロジェクトを作成します。
Xcodeで「File」-「New」-「Target」とたどり「iOS」-「Application」 から「Single View Application」を選択し新しいプロジェクトを作成します。(ここでは、名前を「Demo」としました)
この時点で、XcodeのProjectナビゲータでは、次のような配置になっています。
「Demo」プロジェクトから「MyLib」が参照できるように、「TARGETS」-「Demo」-「General」-「Embedded Binaries」に追加します。 「+」をクリックして表示されたダイアログでは、「MyLib.framewokriOS」を選択します。
追加が完了すると、次のようになります。
この時点で、Demoプロジェクトから利用が可能になっています。
ターゲットを「Demo」に変更して、シュミレーターで実行してみてください。(※当初「MyLib」でプロジェクトを作成したため、Demoに変更する必要があります)
起動時に「MyLib start..」が出力されることを確認できます。
(3) Githubでのリポジトリ作成
次にこのライブラリをGithub上に置くために、新しいリポジトリを作成します。
この時、ライセンスや、READMEのファイル作成もチェックしてgithubに雛形の生成をお願いしましょう。
なお、この時点でGithub上にリポジトリを作成する理由は、次に作成するpodspecファイルの「検証」で必要なためです。
(4) podspecファイル
CocoaPodsに管理させるためには、podspecファイル(メタ情報)が必要です。
MyLibのプロジェクトファイルが存在するフォルダで次のコマンドを打つと、podspecファイル(名前は、ライブラリ名.podspecとなります)の雛形が生成されます。
$ pod spec create MyLib Specification created at MyLib.podspec $ ls -la total 16 drwxr-xr-x 6 SIN staff 204 12 20 15:59 . drwxr-xr-x 36 SIN staff 1224 12 20 14:59 .. drwxr-xr-x 7 SIN staff 238 12 20 15:44 Demo drwxr-xr-x 5 SIN staff 170 12 20 15:04 MyLib -rw-r--r-- 1 SIN staff 6123 12 20 15:59 MyLib.podspec <=作成された雛形 drwxr-xr-x 5 SIN staff 170 12 20 15:41 MyLib.xcodeproj
後は、このファイルを編集しますが、今回編集した内容は次のとおりとなりました。
ライブラリの取得先は、先ほど作成したGithubになっています。
Pod::Spec.new do |s| s.name = "MyLib" s.version = "0.0.1" s.summary = "MyLib" s.license = { :type => 'MIT', :file => 'LICENSE' } s.homepage = "https://github.com/furuya02/MyLib" s.author = { "furuya02" => "[email protected]" } s.source = { :git => "https://github.com/furuya02/MyLib.git", :tag => "#{s.version}" } s.platform = :ios, '8.0' s.source_files = 'MyLib/**/*.{h,m,swift}' end
podspecファイルの各項目の内容は次のようになっています。
名前 | 意味 |
name | 名称 |
version | バージョン |
license | ライセンス |
summary | 説明 |
homepage | 公開URL |
author | 著作者情報 |
source | ソースコード入手先 |
source_files | ライブラリで実際に使用するファイルのパス |
なお、詳しくは、公式のドキュメントをご参照ください。
編集が終了したら、チェックを行います。少し時間がかかりますが、「MyLib passed validation.」が表示されたらOKです。
下記の例では、LICENSEファイルがないという警告が表示されていますが、これは、Github上で先ほど雛形を生成したので、マージした時点で問題なくなります。
$ pod lib lint -> MyLib (0.0.1) MyLib passed validation. [!] Unable to read the license file `/Users/SIN/Documents/work/MyLib/LICENSE` for the spec `MyLib (0.0.1)`
(5) Githubへの公開
Githubへの公開は、次のとおりです。
$ git init <=ローカルリポジトリの初期化 $ git pull https://github.com/furuya02/MyLib.git <=Github上のファイルをpull $ git add . <= ローカルのファイルをステージングする $ git commit -am "initialize" <= コミット $ git remote add origin https://github.com/furuya02/MyLib.git $ git push <= Githubへのpush $ git tag 0.0.1 <= タグの追加 $ git push —tags <= タグをGithubへのpush
マージが終了すると、Github上でtag「0.0.1」で現在の状態が取得できます。
(6) 使用してみる
それでは、今Github上に置いたライブラリを使用してみます。手順は「3 外部ライブラリの使用方法」のところで紹介した要領そのままです。
なお、Podfileの内容は、次のとおり。
use_frameworks! target 'TestApp' do pod 'MyLib', :git => 'https://github.com/furuya02/MyLib.git' end
また、installしている様子は、次のようになっています。
$ pod install Updating local specs repositories Analyzing dependencies Pre-downloading: `MyLib` from `https://github.com/furuya02/MyLib.git` Downloading dependencies Installing MyLib (0.0.1) Generating Pods project Integrating client project [!] Please close any current Xcode sessions and use `TestApp.xcworkspace` for this project from now on. Sending stats Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
Podsプロジェクトの中に組み込まれた「MyLib」を利用できることを確認できます。
5 トラブル対処など
(1) 再インストール
CocoaPods自体の更新は、次のコマンドで可能です。
$ sudo gem update cocoapods
なお、再インストールは次のようになります。
$ sudo gem clean cocoapods <=古いバージョンを削除する場合 $ sudo gem uninstall cocoapods $ sudo gem install cocoapods
(2) 管理情報の再設定
管理情報のフォルダを削除してしまって、setupコマンドで最新情報をダウンロードできます。
$ sudo rm ーfr ~/Library/Caches/CocoaPods/ $ sudo rm ーfr ~/.cocoapods/repos/master/ $ pod setup
(3) プロジェクト内での再構築
プロジェクト内では、Podsフォルダの中にすべての外部ライブラリが入っているので、これを削除して、updateコマンドを使用すると、Podfileの指定に基づいてライブラリが再構築されます。
プロジェクトフォルダに移動して $ rm ーfr Pods/ $ pod update
(4)CocoaPodsをプロジェクトから削除する方法
Podfile、Podfile.lock、Pods、.xcsorkspaceを削除して、プロジェクトファイルから開きます。
$ rm Podfile $ rm Podfile.lock $ rm ーrf Sample001.xcworkspace $ rm ーrf Pods $ ls -la total 8 drwxr-xr-x 5 SIN staff 170 12 17 04:00 . drwxr-xr-x 28 SIN staff 952 12 17 00:56 .. -rw-r--r-- 1 SIN staff 208 12 17 01:59 Podfile drwxr-xr-x 8 SIN staff 272 12 17 03:28 Sample001 drwxr-xr-x@ 5 SIN staff 170 12 17 01:59 Sample001.xcodeproj $ open Sample001.xcodeproj/
ツリーの中で、Pods等不要なファイルを削除します。
この時点でBuildすると、次のようなエラーが発生します。
Podfile.lockやManifest.lockとの連携を切るためには、「TARGETS」の「Build Phases」で次の2つを削除する必要があります。
- Check Pods Manifest.lock
- Copy Pods Resources
6 CocoaPodsのバージョンを統一する方法 [2015.12.22追記]
チーム開発などで、個々の利用しているCocoaPodsのバージョンに相違があって問題となることがあります。ここでは、バージョンを統一する要領について紹介します。
(1) グローバルのバージョン管理
グローバルにインストールされているCocoaPodsのバージョンを任意のものにするには、一旦削除して、バージョンを指定したインストール行うしかありません。
$ pod --version <= バージョンの確認 0.39.0 $ sudo gem uninstall cocoapods --version "=0.39.0" <=アンインストール $ sudo gem install -v 0.38.2 cocoapods <=任意のバージョンのインストール $ pod --version <= バージョンの確認 0.38.2
(2) ローカルのバージョン管理
Bundlerを使用すると、プロジェクト内にCocoaPodsの特定のバージョンを組み込むことができます。
Bundlerとは、Rubyのライブラリ管理ツールです。ここでは、Bundlerのセットアップが完了している前提で進めています。
参考:bundlerでgemをプロジェクトごとに管理する
$ cd project <= プロジェクトフォルダに移動 $ bundle init <= Gemfile(設定ファイル)の雛形作成 $ echo "gem 'cocoapods', '0.32.1'" >> Gemfile <= Gemfileにcocoapodのバージョン0.32.1を使用する指定追加する $ cat Gemfile <= Gemfileの内容を確認する # A sample Gemfile source "https://rubygems.org" # gem "rails" gem 'cocoapods', '0.32.1' $ bundle install --path vender/bundle <= プロジェクトの内(ローカル)にCocoaPodsがインストールされる $ bundle exec pod --version <= プロジェクトの内(ローカル)のCocoaPodsを使用する 0.32.1 $ pod --version <= グローバルのCocoaPodsのバージョンは変化ない 0.39.0
7 まとめ
今回は、定番ツールであるCocoaPodsの利用方法について、外部ライブラリを「利用する立場」と、「作成する立場」の2つの方向でまとめてみました。
当初、「Swiftには対応していない」とのことでしたが、現時点では、全く問題なく利用できることを改めて確認できました。
8 参考リンク
iOSライブラリ管理の神ツール「CocoaPods」のインストールと使い方
stack overflow How to remove CocoaPods from a project?
Should I check the Pods directory into source control?
自前のライブラリをCocoaPodsで管理するメモ